package com.greensam.pixelengine.aop;

import com.greensam.pixelengine.annotation.AuthCheck;
import com.greensam.pixelengine.pojo.emuns.RoleEnum;
import com.greensam.pixelengine.exception.BusinessException;
import com.greensam.pixelengine.exception.ResultCode;
import com.greensam.pixelengine.facade.RoleFacadeService;
import com.greensam.pixelengine.facade.UserFacadeService;
import com.greensam.pixelengine.pojo.entity.RolePo;
import com.greensam.pixelengine.pojo.entity.UserPo;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author Macro_Ray
 * @since 2025/6/19 14:34
 */
@Aspect
@Component
@RequiredArgsConstructor
public class AuthInterceptor {

    private final UserFacadeService userFacadeService;

    private final RoleFacadeService roleFacadeService;

    /**
     * 执行拦截
     *
     * @param joinPoint 切入点
     * @param authCheck 权限校验注解
     * @author Macro_Ray
     * @since 2025/6/19
     */
    @Around("@annotation(authCheck)")
    public Object doInterceptor(ProceedingJoinPoint joinPoint, AuthCheck authCheck) throws Throwable {
        // 需要有的权限
        RoleEnum[] mustRole = authCheck.mustRole();
        if (mustRole == null || mustRole.length == 0) {
            // 无需权限，放行
            return joinPoint.proceed();
        }
        List<String> mustRoleList = Arrays.stream(mustRole)
                .map(RoleEnum::getCode)
                .toList();

        // 获取当前登录用户
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        UserPo loginUser = userFacadeService.getLoginUser(request);
        if (loginUser == null) {
            throw new BusinessException(ResultCode.NOT_LOGIN_ERROR);
        }
        // 该用户的角色权限
        List<RolePo> rolePos = roleFacadeService.listRoleByUserId(loginUser.getId());
        if (CollectionUtils.isEmpty(rolePos)) {
            // 角色没有授权
            throw new BusinessException(ResultCode.NO_AUTH_ERROR);
        }
        Set<String> roleCodeList = rolePos.stream()
                .map(RolePo::getCode)
                .collect(Collectors.toSet());

        // 用户是否有任意一个所需角色权限
        boolean hasPermission = mustRoleList.stream().anyMatch(roleCodeList::contains);
        if (!hasPermission) {
            throw new BusinessException(ResultCode.NO_AUTH_ERROR);
        }
        return joinPoint.proceed();
    }
}
